package cn.com.dbappsecurity.frame.request;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringUtils;

/**
 * 处理文件上传
 * @author dhz
 */
public class MultipartRequest extends HttpServletRequestWrapper {

	private HttpServletRequest request;
	//允许上传的最大文件
	private Long fileMaxSize;
	//编码
	private String encode;

	private Map<String, List<String>> parameters = new HashMap<String, List<String>>();
	private Map<String, List<FileItem>> multipartFiles = new HashMap<String,List<FileItem>>();

	//最多只允许在内存中存储的数据,单位:字节
	private static final Integer FILE_MEM_MAX_SIZE = 1024 * 10;
	
	/**
	 * 构造函数
	 * @param request
	 * @param fileMaxSize	允许上传的最大文件
	 * @param encode		文件编码
	 * @throws FileUploadException 
	 * @throws UnsupportedEncodingException 
	 * @throws FrameException 
	 */
	public MultipartRequest(HttpServletRequest request,Long fileMaxSize,String encode)
	throws UnsupportedEncodingException, FileUploadException{
		super(request);
		this.request = request;
		this.fileMaxSize = fileMaxSize;
		this.encode = encode;
		this.processUpload();
	}

	/**
	 * 获取参数
	 */
	public String getParameter(String name){
		List<String> v = parameters.get(name);
		if (v != null && v.size() > 0) {
			return v.get(0);
		}
		return super.getParameter(name);
	}

	/**
	 * 获取参数
	 */
	public String[] getParameterValues(String name) {
		List<String> v = parameters.get(name);
		if (v != null && v.size() > 0) {
			return v.toArray(new String[v.size()]);
		}
		return null;
	}
	
	/**
	 * 获取文件
	 * @param name
	 * @return
	 */
	public FileItem getFile(String name) {
		List<FileItem> files = multipartFiles.get(name);
		if (files != null && files.size() > 0) {
			return files.get(0);
		}
		return null;
	}

	/**
	 * 获取文件
	 * @param name
	 * @return
	 */
	public FileItem[] getFiles(String name) {
		List<FileItem> files = multipartFiles.get(name);
		return files == null ? null : files.toArray(new FileItem[files.size()]);
	}
	
	/*
	 * 执行上传文件
	 * @throws FileUploadException
	 * @throws UnsupportedEncodingException
	 */
	private void processUpload() throws FileUploadException,UnsupportedEncodingException{
		DiskFileItemFactory factory = new DiskFileItemFactory();
		//最多只允许在内存中存储的数据,单位:字节
		factory.setSizeThreshold(FILE_MEM_MAX_SIZE);
		//设置临时目录
		factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
		ServletFileUpload upload = new ServletFileUpload(factory);
		//允许上传的最大文件
		if(fileMaxSize > 0){
			upload.setFileSizeMax(fileMaxSize);
		}
		List<?> fileItems = upload.parseRequest(request);
		for(Object obj : fileItems){
			FileItem item = (FileItem)obj;
			//判断是form表单域还是上传文件file域
			if (item.isFormField()) {
				processNormalFormField(item);
			} else {
				processFileField(item);
			}
		}
	}
	
	/*
	 * 处理文件域
	 * @param item
	 */
	private void processFileField(FileItem item){
		if (StringUtils.isBlank(item.getName())) {
			return;
		}
		String fieldName = item.getFieldName();
		List<FileItem> values = multipartFiles.get(fieldName);
		if(values == null){
			values = new ArrayList<FileItem>();
			multipartFiles.put(fieldName,values);
		}
		values.add(item);
	}

	/*
	 * 处理表单域
	 * @param item
	 * @throws UnsupportedEncodingException
	 */
	private void processNormalFormField(FileItem item) throws UnsupportedEncodingException{
		String fieldName = item.getFieldName();
		List<String> values = parameters.get(fieldName);
		if (values == null) {
			values = new ArrayList<String>();
			parameters.put(fieldName,values);
		}
		values.add(new String(item.get(),encode));
	}

}
